pragma License (GPL);
--
-- drk-bigint-mul.adb
--
-- Copyright (C) 2012 - Thibault BUREL
--
-- This file is part of DRK.BigRat.
--
-- DRK.BigRat is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- DRK.BigRat is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with DRK.BigRat.  If not, see <http://www.gnu.org/licenses/>
--

separate(DRK.BigInt)
function Mul(Left  : in Instance;
             Right : in Instance) return Instance
is

   Result : Instance := Init(0);

   CL : Digit_List.Cursor := Left.Mantissa.First;
   CR : Digit_List.Cursor := Right.Mantissa.First;

   L, R         : Chunck;

   Scale_Factor_Left  : Natural;
   Scale_Factor_Right : Natural;

begin

   Scale_Factor_Left := 0;
   CL                := Left.Mantissa.First;
   while CL /= Digit_List.No_Element loop

      L := Digit_List.Element(CL);

      Scale_Factor_Right := 0;
      CR                 := Right.Mantissa.First;
      while CR /= Digit_List.No_Element loop

         declare
            Count : Natural := Scale_Factor_Left + Scale_Factor_Right;
            Tmp : Instance;
         begin

            while Count > 0 loop

               Digit_List.Append(Tmp.Mantissa, 0);

               Count := Count - 1;

            end loop;

            R := Digit_List.Element(CR);

            declare
               M : constant Double_Chunck := Mul (L, R);
            begin
               Digit_List.Append(Tmp.Mantissa, M(1));

               if M (2) /= 0 then
                  --  This branch is tested indirectly by BigRat.Less_06 and
                  --  BigRat.Less_07

                  Digit_List.Append(Tmp.Mantissa, M(2));

               end if;

            end;

            Result := Result + Tmp;

         end;

         Scale_Factor_Right := Scale_Factor_Right + 1;
         CR := Digit_List.Next (CR);

      end loop;

      Scale_Factor_Left := Scale_Factor_Left + 1;
      CL := Digit_List.Next (CL);

   end loop;

   return Result;

end Mul;

